package com.example.test.conview.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.view.MotionEvent;

import com.puty.conputyutils.CheckDoubleClickUtils;
import com.puty.conputyutils.LeoUtils;
import com.puty.conputyutils.LogUtils;
import com.puty.conputyutils.ToastUtils;
import com.puty.conputyview.R;
import com.puty.conputyview.common.PutyConst;
import com.puty.conputyview.interfaces.DragOnTouchCallBack;
import com.puty.conputyview.view.core.BaseElement;
import com.puty.conputyview.view.core.Element;
import com.puty.conputyview.view.core.TableElement;

import java.util.Date;
import java.util.List;

public class DragView extends BaseDrag{
    private final static String TAG = "DragView";

    /**
     * 点击间隔时间差
     */
    private final int DOWN_INTERVAL_TIME = 500;

    /**
     * x轴坐标
     */
    private int xShaft = 0;

    /**
     * y轴坐标
     */
    private int yShaft = 0;

    /**
     * 画笔
     */
    private Paint mPaint;

    /**
     * 按下时间
     */
    private long lstDownTime = 0;
    /**
     * 左右边线距离
     */
    private float sideLineDistanceAboutx = 0;

    /**
     * 左右边线距离
     */
    private float sideLineDistanceAbouty = 0;

    /**
     * 事件处理回调接口对象
     */
    private DragOnTouchCallBack mDragOnTouchCallBack;

    public DragView(Context context, int width, int height) {
        super(context, width, height);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(getResources().getColor(R.color.black2));
        mPaint.setStrokeWidth(3);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setPathEffect(new DashPathEffect(new float[]{5, 5}, 0));
    }
    /**
     * 刷新镜像
     */
    public void refreshImage() {
        LogUtils.i(TAG, "refreshImage");
    }

    /**
     * 触摸事件处理
     *
     * @param event 事件对象
     */
    public void onTouch(MotionEvent event ,DragOnTouchCallBack dragOnTouchCallBack) {
        mDragOnTouchCallBack = dragOnTouchCallBack;
        if (this.lb.isLock == 1) {
            //设置元素的属性或者标签属性
            elementChangeNoitcs(null);
            return;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN://手指 初次接触到屏幕 时触发。
                actionDown(event);
                break;
            case MotionEvent.ACTION_MOVE://	手指 在屏幕上滑动 时触发，会多次触发
                actionMove(event);
                break;
            case MotionEvent.ACTION_UP://	手指 离开屏幕 时触发。
                actionUp(event);
                break;
        }
    }

    /**
     * 抬起事件处理
     *
     * @param event 事件对象
     */
    private void actionUp(MotionEvent event) {
        if (ACTION == PutyConst.ACTION_TOUCH_MOVE && currentElement != null) {
            // 选中状态下再次点击（表格选择单元格）
            currentElement.selecting(point.x, point.y);
            // 多选状态下如果选中为表格则点击不取消选中
            if (currentElement.type == 5 && ((TableElement) currentElement).selecting) {
            } else {
                // 多选状态下选中元素，再次点击则取消
                currentElement.isselected = currentElement.ismoving ? true : (currentElement.isselected ? false : true);
            }
        }

        if (currentElement != null) {
            currentElement.ismoving = false;
        }

        if (currentElement == null || (currentElement != null && currentElement.isselected)) {
            elementChangeNoitcs(currentElement);
        }

        this.ACTION = PutyConst.ACTION_TOUCH_DEFAULT;
        int isMunSelect = lb.isMunSelect;
        lb.isMunSelect = 0;
        if (currentElement != null && currentElement.isselected && this.ACTION == PutyConst
                .ACTION_TOUCH_DEFAULT) {
            //克隆备份
            int xx = (int) (Math.abs(xShaft - event.getX()) + Math.abs(yShaft - event.getY()));
            if (xx > 5 && mDragOnTouchCallBack != null) {
                // 移动前克隆备份
                mDragOnTouchCallBack.onAddRecord();
            }
        }
        lb.isMunSelect = isMunSelect;
        for (BaseElement el : lb.Elements) {//点击空白区域时，表格内单元格选中取消
            if (el.type == 5 && ((TableElement) el).isselected == false) {
                ((TableElement) el).callarray = "";
                el.init();
            }
        }
        elementChangeNoitcs(currentElement);
        this.invalidate();
        refreshImage();
    }

    /**
     * 滑动事件处理
     *
     * @param event 事件对象
     */
    private void actionMove(MotionEvent event) {
        if (ACTION == PutyConst.ACTION_TOUCH_DOUBLE_CLICK) {
            // 双击事件不处理
            LogUtils.i(TAG,"actionMove ---> 双击事件不处理");
            return;
        }
        int mXShaft = (int) event.getX();
        int mYShaft = (int) event.getY();
        float scale = 1;
        // 判断是否在移动
        if ((point.x - scale <= mXShaft && point.x + scale >= mXShaft) &&
                (point.y - scale <= mXShaft && point.y + scale >= mYShaft)){
            // 没有在移动
            LogUtils.i(TAG,"actionMove ---> 没有在移动");
            return;
        } else {
            //是在移动
            ACTION = ACTION == PutyConst.ACTION_TOUCH_DEFAULT ? PutyConst.ACTION_TOUCH_MOVE : ACTION;
            if (currentElement != null) {
                //移动则取消普通点击两次（表格取消单元格操作）
                currentElement.selecting(false);
            }
        }
        //多选时，单击取消选中
        if (ACTION == PutyConst.ACTION_TOUCH_MOVE && currentElement != null) {
            //是被选中
            currentElement.isselected = true;
            //是移动
            currentElement.ismoving = true;
        }
        int isMunSelect = lb.isMunSelect;
        lb.isMunSelect = 0;
        Move(mXShaft - point.x, mYShaft - point.y, new PointF(mXShaft, mYShaft));
        lb.isMunSelect = isMunSelect;
        this.invalidate();
    }

    /**
     * 移动处理
     *
     * @param xShaft x轴坐标
     * @param yShaft y轴坐标
     * @param newpoint PointF 对象
     * @return 是否拦截事件
     */
    private boolean Move(float xShaft, float yShaft, PointF newpoint) {
        List<BaseElement> list = lb.Elements;
        if (ACTION == PutyConst.ACTION_TOUCH_MOVE) {
            int padding = 8;
            boolean upmove = true;//判断是否可上移
            boolean downmove = true;//判断是否可下移
            boolean leftmove = true;//判断是否可左移
            boolean rightmove = true;//判断是否可右移
            for (BaseElement el : list) {//循环判断所有选中元素
                if (!el.isselected) continue;
                if (el.isLock == 1) {
                    if (!CheckDoubleClickUtils.isDoubleClick(3000)) {
                        ToastUtils.showToast(LeoUtils.getApplication()
                                .getString(R.string.element_is_locked));
                    }
                    continue;
                }
                if (el.left <= padding) {
                    leftmove = false;//多选模式下一个不可左移，则都不可左移
                }
                if ((el.left + el.width + padding) >= this.getWidth()) {
                    rightmove = false;//多选模式下一个不可右移，则都不可右移
                }
                if (el.top <= padding) {
                    upmove = false;//多选模式下一个不可上移，则都不可上移
                }
                if ((el.top + el.height + padding) >= this.getHeight()) {
                    downmove = false;//多选模式下一个不可下移，则都不可下移
                }
            }

            //移动
            for (BaseElement element : list) {
                if (!element.isselected) {
                    continue;
                }
                if (element.isLock == 1) {
                    if (!CheckDoubleClickUtils.isDoubleClick(3000))
                        ToastUtils.showToast(LeoUtils.getApplication()
                                .getString(R.string.element_is_locked));
                    continue;
                }
                //判断边界问题
                if (xShaft <= 0) {
                    if (element.width >= this.getWidth()) {
                        element.left += xShaft;
                    } else {
                        if (leftmove) {
                            if (element.left > padding) {
                                element.left += xShaft;
                            } else {
                                element.left = padding;
                            }
                        }
                    }
                    //不出打印区域
                } else {
                    if (element.width >= this.getWidth()) {
                        element.left += xShaft;
                    } else {
                        if (rightmove) {
                            if ((element.left + element.width + padding) < this.getWidth()) {
                                element.left += xShaft;
                            } else {
                                element.left = this.getWidth() - element.width - padding;
                            }
                        }
                    }
                }
                if (yShaft <= 0) {
                    if (element.height >= this.getHeight()) {
                        element.top += yShaft;
                    } else {
                        if (upmove) {
                            if (element.top > padding) {
                                element.top += yShaft;
                            } else {
                                element.top = padding;
                            }
                        }
                    }
                } else {
                    if (element.height >= this.getHeight()) {
                        element.top += yShaft;
                    } else {
                        if (downmove) {
                            if ((element.top + element.height + padding) < this.getHeight()) {
                                element.top += yShaft;
                            } else {
                                element.top = this.getHeight() - element.height - padding;
                            }
                        }
                    }
                }
            }
        } else if (ACTION == PutyConst.ACTION_TOUCH_SCALE) {
            //缩放
            for (BaseElement element : list) {
                if (element.isLock == 1) {
                    continue;
                }
                if (!element.isselected) {
                    continue;
                }
                element.zoom(xShaft, yShaft, this.getWidth(), this.getHeight());
            }
        }
        point = newpoint;
        return true;
    }

    /**
     * 按下事件处理
     *
     * @param event 事件对象
     */
    private void actionDown(MotionEvent event) {
        xShaft = (int) event.getX();
        yShaft = (int) event.getY();
        point.x = (int) event.getX();
        point.y = (int) event.getY();
        BaseElement element = getScale(point.x, point.y);//确认按下的点是否在  横向放缩
        BaseElement delete = getDelete(point.x, point.y);
        // 判断是否点击缩放区域
        if (element != null) {
            //非多选模式
            if (lb.isMunSelect == 0) {
                setUnSelected();
            }
            element.isselected = true;
            element.iszoom = true;
            this.ACTION = PutyConst.ACTION_TOUCH_SCALE;//缩放
        } else {
            //判断是否点击删除区域
            if (delete != null) {
                // 是否点击选中当前元素了
                if (delete.isselected && mDragOnTouchCallBack != null) {
                    //  删除元素
                    mDragOnTouchCallBack.onDeleteView();
                }
            }
            element = getSelected(point.x, point.y);
            if (element != null) {
                element.selecting();//选中状态下再次点击（表格选择单元格）
            }
            //单选模式 取消所有元素选中
            if (lb.isMunSelect == 0) {
                if (element != null && element.type == PutyConst.TABLE && element ==
                        currentElement && ((TableElement) element).isMunSelect == 1) {
                    // 表格的处理
                } else {
                    for (BaseElement el : lb.Elements) {
                        el.isselected = false;
                        el.iszoom = false;
                    }
                }
            }
            if (element != null) {
                long delay = new Date().getTime();
                if (lstDownTime <= 0) {
                    lstDownTime = delay;
                } else {
                    delay = delay - lstDownTime;
                    if (DOWN_INTERVAL_TIME >= delay) {
                        if (currentElement != null && currentElement.entityId
                                .equals(element.entityId)) {
                            this.ACTION = PutyConst.ACTION_TOUCH_DOUBLE_CLICK;//表示双击
                        }
                    }
                    lstDownTime = new Date().getTime();
                }
                if (this.ACTION != PutyConst.ACTION_TOUCH_DOUBLE_CLICK) {
                    this.ACTION = PutyConst.ACTION_TOUCH_MOVE;//移动 非缩放
                }
            }
        }
        //当前选中的元素
        currentElement = element;
        //判断是否双击
        if (this.ACTION == PutyConst.ACTION_TOUCH_DOUBLE_CLICK && currentElement != null) {

            // 只处理 文本、一维码、二维码、表格类型元素事件
            if (currentElement.type <= PutyConst.QR_CODE || currentElement.type == PutyConst.TABLE) {
                if (mDragOnTouchCallBack == null || currentElement == null) {
                    LogUtils.i(TAG, "actionDown ---> mDragOnTouchCallBack == null or currentElement == null");
                    return;
                }
                mDragOnTouchCallBack.onDoubleClick(currentElement.type);
            }
        }
        this.invalidate();
    }

    /**
     * 发送消息更新
     */
    public void sendNoitcs() {
        elementChangeNoitcs(setSelectede());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (sideLineDistanceAboutx > 0 && sideLineDistanceAbouty > 0) {//编辑范围框
            mCanvas.drawRoundRect(new RectF(
                            sideLineDistanceAboutx * 8 * lb.scale,
                            sideLineDistanceAbouty * 8 * lb.scale,
                            width - sideLineDistanceAboutx * 8 * lb.scale,
                            height - sideLineDistanceAbouty * 8 * lb.scale
                    ),
                    0,
                    0,
                    mPaint);
        }

        refresh(mCanvas);
        /**最后通过canvas一次性的把mBufferBitmap绘制到屏幕上**/
        if (mBufferBitmap != null && !mBufferBitmap.isRecycled()) {
            canvas.drawBitmap(mBufferBitmap, 0, 0, null);
        }
    }

    private void refresh(Canvas canvas) {
        if (lb == null) {
            LogUtils.i(TAG,"refresh ---> lb == null");
            return;
        }
        List<BaseElement> list = lb.Elements;
        int len = list.size();
        for (int i = 0; i < len; i++) {
            Element el = (Element) list.get(i);
            el.isShow = true;
            el.init();
            el.draw(canvas);

//           LogUtils.e("编辑界面  字体大小  " + el.fontSize  + "  字间距 " + el.textCellSpace+ "  元素类型 " + el.type  + "  fontIndex "  +  el.fontIndex + "   width "  +  el.width + " height "  +  el.height + "标签的宽度" + lb.Width + "标签的高度" +  lb.Height);

            if (el.isMirror && lb.mirrorLabelType != 1 && lb.mirrorLabelType != 2) {//镜像旋转对称
                try {
                    Element temp = el.clone();//复制对象
                    temp.left = width - el.width - el.left;
                    temp.top = height - el.height - el.top;
                    if (lb.isCableLabelInt == 1) {// 有尾巴
                        if (lb.tailDirectionInt == 1) {//上
                            temp.top = height - el.height - el.top + (height / lb
                                    .Height * (float) lb.tailLengthDouble);
                        } else if (lb.tailDirectionInt == 2) {//下
//                                temp.top = (h/lb.Height*(float)lb.tailLengthDouble) - el.height - el.top - (h/lb.Height*(sideLineDistanceAbouty*2));
                            temp.top = (width * (lb.Height - (float) lb.tailLengthDouble) / lb
                                    .Width) - el.height - el.top;
                        } else if (lb.tailDirectionInt == 3) {//左
                            temp.left = width - el.width - el.left + (width / lb.Width * (float) lb.tailLengthDouble);
                        } else if (lb.tailDirectionInt == 4) {//右
//                                temp.left = (w/lb.Width*(float)lb.tailLengthDouble) - el.width - el.left - (w/lb.Width*(sideLineDistanceAboutx*2));
                            temp.left = (height * (lb.Width - (float) lb.tailLengthDouble) / lb
                                    .Height) - el.width - el.left;
                        }
                    }
                    if (el.rate == PutyConst.RATE_0) {
                        temp.rate = PutyConst.RATE_180;
                    } else if (el.rate == PutyConst.RATE_90) {
                        temp.rate = PutyConst.RATE_270;
                    } else if (el.rate == PutyConst.RATE_180) {
                        temp.rate = PutyConst.RATE_0;
                    } else if (el.rate == PutyConst.RATE_270) {
                        temp.rate = PutyConst.RATE_90;
                    }
                    temp.setFontSize();
                    temp.init();
                    temp.draw(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (el.isselected) {
                canvas.drawLine(el.left - 5, 0, el.left - 5, getHeight(), mPaint);
                canvas.drawLine(el.left + 5 + el.width, 0, el.left + 5 + el.width, getHeight(), mPaint);
                canvas.drawLine(0, el.top - 5, getWidth(), el.top - 5, mPaint);
                canvas.drawLine(0, el.top + 5 + el.height, getWidth(), el.top + 5 + el.height, mPaint);
            }
        }
    }

    /**
     * 设置画布
     *
     * @param width 宽
     * @param height 高
     */
    public void setcanvas(int width, int height) {

        setWillNotDraw(false);
        this.width = width;
        this.height = height;
        Bitmap bitmap = createBitmap(width, height);
        if (bitmap != null) {
            if (mBufferBitmap != null && !mBufferBitmap.isRecycled()) {
                mBufferBitmap.recycle();
                mBufferBitmap = null;
            }
            mBufferBitmap = bitmap;
        }
        if (mBufferBitmap != null && !mBufferBitmap.isRecycled()) {
            mCanvas.setBitmap(mBufferBitmap);
        }
        sideLineDistanceAboutx = lb.getSideLineDistance(true);
        sideLineDistanceAbouty = lb.getSideLineDistance(false);
    }

    /**
     * 生成Bitmap对象
     *
     * @param width 宽
     * @param height 高
     * @return Bitmap对象
     */
    private Bitmap createBitmap(int width, int height) {
        try {
            return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError e) {
            return null;
        }
    }
}
